type Ab__get_callback__bA<T, prop extends keyof T> = (proxy: T, value: T[prop])=>T[prop];
type Ab__set_callback__bA<T, prop extends keyof T> = (proxy: T, old: T[prop], value: T[prop])=>T[prop];

/** 代理拦截数据 */
export type Ab_DataBlocker_bA<T> = {
	Ab_get_bA?: {[prop in keyof T]?: Ab__get_callback__bA<T, prop>}&{ignore?: Array<abi.Ab_OmitKeys_bA<T, Function>>},
	Ab_set_bA?: {[prop in keyof T]?: Ab__set_callback__bA<T, prop>}&{ignore?: Array<abi.Ab_OmitKeys_bA<T, Function>>},
	Ab_afterSet_bA?: (prop: string|symbol, old: any, value: any, hdl: Ab_PxiHandle_bA<T>)=>void;
}

export class Ab_PxiHandle_bA<T extends Object|Array<any>> implements ProxyHandler<T>{

	constructor(private Ab_tgt_bA: T, private Ab_name_bA: string, private Ab_prt_bA: Ab_PxiHandle_bA<any>, private Ab_blocker_bA?:Ab_DataBlocker_bA<T>){
		if(Ab_blocker_bA) this.Ab_in_bA(Ab_blocker_bA);
		this.Ab_revocable_bA = Proxy.revocable(Ab_tgt_bA, this);
		this.Ab_old_bA = (Array.isArray(Ab_tgt_bA)?[]:{}) as T;
		this.Ab_backup_bA();
	}

	private Ab_getGetCall_bA<prop extends keyof T>(key: prop): Ab__get_callback__bA<T, prop>{
		let call: Ab__get_callback__bA<T, prop>;
		if(this.Ab_blocker_bA && this.Ab_blocker_bA.Ab_get_bA && Reflect.has(this.Ab_blocker_bA.Ab_get_bA, key)) call = Reflect.get(this.Ab_blocker_bA.Ab_get_bA, key) as Ab__get_callback__bA<T, prop>;
		return call;
	}

	private Ab_getSetCall_bA<prop extends keyof T>(key: prop): Ab__set_callback__bA<T, prop>{
		let call: Ab__set_callback__bA<T, prop>;
		if(this.Ab_blocker_bA && this.Ab_blocker_bA.Ab_set_bA && Reflect.has(this.Ab_blocker_bA.Ab_set_bA, key)) call = Reflect.get(this.Ab_blocker_bA.Ab_set_bA, key) as Ab__set_callback__bA<T, prop>;
		return call;
	}

	private Ab_backup_bA(key?: any){
		let value: any;
		if(key===undefined){
			value = abi.Ab_cloneData_bA(this.Ab_target_bA);
			this.Ab_old_bA = value;
		}else{
			value = Reflect.get(this.Ab_target_bA, key);
			value = abi.Ab_cloneData_bA(value);
			Reflect.set(this.Ab_old_bA, key, value);
		}

		return value;
	}

	valueOf(){
		let temp: any;
		if(Array.isArray(this.Ab_tgt_bA)){
			temp = [];
			let proxy = this.Ab_proxy_bA as Array<any>;
			for(let i = 0; i < proxy.length; i++) temp.push(Reflect.get(proxy, i));
		}else{
			temp = {};
			let proxy = this.Ab_proxy_bA as Object;
			Reflect.ownKeys(proxy).forEach(key=>Reflect.set(temp, key, Reflect.get(proxy, key)));
		}

		return temp as T;
	}

	private async Ab_publish_bA(key: string|symbol, old: any, value: any){
		if(key!==undefined){
			let path = this.Ab_path_bA + '.' + String(key);
			Ab_DataTransfer_bA.Ab_publish_bA(path, old, value);
		}

		if(this.Ab_parent_bA) this.Ab_parent_bA.Ab_publish_bA(this.Ab_name_bA, this.Ab_old_bA, this.Ab_target_bA);
	}

	public Ab_in_bA(blocker: Ab_DataBlocker_bA<T>){
		if(this.Ab_blocker_bA === undefined) this.Ab_blocker_bA = {};
		let props: any[] = [];
		if(Reflect.has(blocker, 'get')){
			if(this.Ab_blocker_bA.Ab_get_bA === undefined) this.Ab_blocker_bA.Ab_get_bA = {};
			Reflect.ownKeys(blocker.Ab_get_bA).forEach(p=>{
				Reflect.set(this.Ab_blocker_bA.Ab_get_bA, p, Reflect.get(blocker.Ab_get_bA, p));
				if(!props.includes(p)) props.push(p);
			});
		}
		if(Reflect.has(blocker, 'set')){
			if(this.Ab_blocker_bA.Ab_set_bA === undefined) this.Ab_blocker_bA.Ab_set_bA = {};
			Reflect.ownKeys(blocker.Ab_set_bA).forEach(p=>{
				Reflect.set(this.Ab_blocker_bA.Ab_set_bA, p, Reflect.get(blocker.Ab_set_bA, p));
				if(!props.includes(p)) props.push(p);
			});
		}
		Reflect.ownKeys(blocker).filter(k=>!['get', 'set'].includes(k as any))
		.forEach(p=>Reflect.has(blocker, p)?Reflect.set(this.Ab_blocker_bA, p, Reflect.get(blocker, p)):void 0);

		props.filter(p=>{
			let value = Reflect.get(this.Ab_tgt_bA, p);
			return typeof value === 'object' && value !== null;
		}).forEach(p=>{
			let value = Reflect.get(this.Ab_tgt_bA, p);
			if(!this.Ab_children_bA.has(p) || this.Ab_children_bA.get(p).Ab_target_bA!==value){
				let handle = Ab_DataTransfer_bA.Ab_proxy_bA(value, String(p), this).Ab_handle_bA;
				this.Ab_children_bA.set(p, handle);
			}
		});
	}

	/** 销毁所有代理 */
	public Ab_destroy_bA(){
		this.Ab_children_bA.forEach(h=>h.Ab_destroy_bA());
		this.Ab_children_bA.clear();
		Ab_DataTransfer_bA.Ab_destroy_bA(this);
		this.Ab_revocable_bA.revoke();
	}

	get(target: T, prop: string|symbol, receiver: any): T[keyof T]{
		let value: any;
		if(this.Ab_blocker_bA?.Ab_get_bA?.ignore?.includes(prop as any)) value = Reflect.get(target, prop);
		else{
			value = this.Ab_children_bA.has(prop) ? this.Ab_children_bA.get(prop).Ab_proxy_bA : Reflect.get(target, prop);

			if(typeof value === 'function') value = Reflect.apply(Function.bind, value, [receiver]);
			else{
				let call = this.Ab_getGetCall_bA(prop as any);
				value = call ? call(receiver, value) : value;
			}
		}

		if(typeof value === 'object' && value !== null && !this.Ab_children_bA.has(prop)){
			let handle = Ab_DataTransfer_bA.Ab_proxy_bA(value, String(prop), this).Ab_handle_bA;
			this.Ab_children_bA.set(prop, handle);
		}

		return value;
	}

	set(target: T, prop: string|symbol, value: any, receiver: any): boolean{
		if(this.Ab_blocker_bA && this.Ab_blocker_bA.Ab_set_bA && this.Ab_blocker_bA.Ab_set_bA.ignore && this.Ab_blocker_bA.Ab_set_bA.ignore.includes(prop as any)){
			Reflect.set(target, prop, undefined);
			return true;
		}

		let old = this.Ab_backup_bA(prop);

		let call = this.Ab_getSetCall_bA(prop as any);
		if(typeof value === 'object' && value !== null && !this.Ab_children_bA.has(prop)){
			let handle = Ab_DataTransfer_bA.Ab_proxy_bA(value, String(prop), this).Ab_handle_bA;
			this.Ab_children_bA.set(prop, handle);
		}

		let new_value = call ? call(receiver, old, value) : value;
		if(this.Ab_children_bA.has(prop) && this.Ab_children_bA.get(prop).Ab_target_bA !== new_value){
			let hdl = this.Ab_children_bA.get(prop);
			if(!new_value){
				hdl.Ab_destroy_bA();
				this.Ab_children_bA.delete(prop);
			}else if(Array.isArray(new_value)){
				hdl.Ab_proxy_bA.splice(0, hdl.Ab_proxy_bA.length);
				hdl.Ab_proxy_bA.push(...new_value);
			}else Object.assign(hdl.Ab_proxy_bA, new_value);
		}

		Reflect.set(target, prop, this.Ab_children_bA.has(prop) ? this.Ab_children_bA.get(prop).valueOf() : new_value);

		if(this.Ab_blocker_bA?.Ab_afterSet_bA) this.Ab_blocker_bA.Ab_afterSet_bA(prop, old, new_value, this);

		this.Ab_publish_bA(prop, old, new_value);

		return true;
	}

	private Ab_revocable_bA: ReturnType<typeof Proxy.revocable>;
	private Ab_old_bA: T;
	/** 本级代理 */
	public get Ab_proxy_bA(){
		return this.Ab_revocable_bA.proxy as T;
	}
	/** 代理对象 */
	public get Ab_target_bA(){
		return this.Ab_tgt_bA;
	}
	/** 父级handle */
	public get Ab_parent_bA(){
		return this.Ab_prt_bA;
	}
	/** 子级handle */
	private Ab_children_bA = new Map<any, Ab_PxiHandle_bA<any>>();
	/** 当前handle的路径 */
	public get Ab_path_bA(): string{
		return this.Ab_parent_bA ? this.Ab_parent_bA.Ab_path_bA+'.'+this.Ab_name_bA : this.Ab_name_bA;
	}
}

export class Ab_DataTransfer_bA{

    /** 代理句柄映射 */
	private static Ab_id_map_bA: Map<any, string> = new Map();
	private static Ab_record_bA: Map<string, [any, any, Ab_PxiHandle_bA<any>]> = new Map();

    /**
     * 生成代理对象
     * @param ins 数据实例
     * @param name 数据名称
     */
    public static Ab_proxy_bA<I extends Object>(ins: I, name?: string, parent: Ab_PxiHandle_bA<any> = null){
		let Ab_proxy_bA: I, Ab_handle_bA: Ab_PxiHandle_bA<I>;
		if(this.Ab_id_map_bA.has(ins)){
			let id = this.Ab_id_map_bA.get(ins);
			let [target, pxi, handle] = this.Ab_record_bA.get(id);
			Ab_proxy_bA = pxi, handle = handle;
		}else{
			let now = Date.now();
			let id = [now, String(Math.round(Math.random()*100000)).padStart(5, '0')].join(':');
			while(this.Ab_record_bA.has(id)) id = [now, String(Math.round(Math.random()*100000)).padStart(5, '0')].join(':');

			//let result = createProxy(ins, name??id);
			Ab_handle_bA = new Ab_PxiHandle_bA(ins, name??id, parent);
			Ab_proxy_bA = Ab_handle_bA.Ab_proxy_bA;

			[ins, Ab_handle_bA, Ab_handle_bA.Ab_proxy_bA].forEach(i=>this.Ab_id_map_bA.set(i, id));
			this.Ab_record_bA.set(id, [ins, Ab_handle_bA.Ab_proxy_bA, Ab_handle_bA]);
		}

        return {Ab_proxy_bA, Ab_handle_bA};
    }

	/** 是否已注册代理 */
	public static Ab_hasProxy_bA(ins: any){
		return this.Ab_id_map_bA.has(ins);
	}

	/**
	 * 初始化一个代理
	 * @param target 代理对象
	 * @param save 是否需要本地存储
	 * @param init 初始化句柄的回调
	 * @returns
	 */
	public static Ab_initProxy_bA<D>(name: string, target: D, save: boolean = false, blocker?: Ab_DataBlocker_bA<D>, prefix?: string){
		let result = Ab_DataTransfer_bA.Ab_proxy_bA(target, name);
		if(save){
			let item_key = (prefix??'')+name;
			abi.Ab_local_bA.Ab_read_bA(item_key, target);
			result.Ab_handle_bA.Ab_in_bA({
				Ab_afterSet_bA(prop, old, valu, handle){
					abi.Ab_local_bA.Ab_save_bA(item_key, handle.Ab_target_bA);
				}
			});
		}

		if(blocker) result.Ab_handle_bA.Ab_in_bA(blocker);

		Reflect.set(globalThis, 'data_'+name, result.Ab_proxy_bA);

		return result.Ab_proxy_bA
	}

	/** 销毁监听代理和记录 */
    public static Ab_destroy_bA<D extends Object>(data: D){
		if(this.Ab_id_map_bA.has(data)){
			let id = this.Ab_id_map_bA.get(data);
			let [ins, pxi, handle] = this.Ab_record_bA.get(id);
			[ins, pxi, handle].forEach(i=>this.Ab_id_map_bA.delete(i));
			let path_list: string[] = [];
			let path = handle.Ab_path_bA;
			this.Ab_call_pool_bA.forEach((l, p)=>p.startsWith(path)?path_list.push(p):void 0);
			path_list.forEach(p=>this.Ab_call_pool_bA.delete(p));
			handle.Ab_destroy_bA();
			this.Ab_record_bA.delete(id);
		}
    }


	private static Ab_monitor_call_bA = new Map<string, Array<(path: string, old: any, value: any)=>void>>();
	public static Ab_monitor_bA(data: Object, call: (path: string, old: any, value: any)=>void){
		let id = this.Ab_id_map_bA.get(data);
		let [ins, pxi, hdl] = this.Ab_record_bA.get(id);
		let path = hdl.Ab_path_bA;
		if(!this.Ab_monitor_call_bA.has(path)) this.Ab_monitor_call_bA.set(path, []);
		this.Ab_monitor_call_bA.get(path).push(call);
	}

	public static Ab_free_bA(data: Object){
		let id = this.Ab_id_map_bA.get(data);
		let [ins, pxi, hdl] = this.Ab_record_bA.get(id);
		let path = hdl.Ab_path_bA;
		if(this.Ab_monitor_call_bA.has(path)) this.Ab_monitor_call_bA.delete(path);
	}

    /** 监听回调池 */
    private static Ab_call_pool_bA: Map<string, Function[]> = new Map();
    /**
     * 注册监听
     * @param data 要监听的数据
     * @param key 要监听的字段
     * @param call 更新时触发的回调函数
     * @param update 是否在注册时触发回调
     */
    public static Ab_follow_bA<D extends Object, K extends abi.Ab_OmitKeys_bA<D, Function>>(data: D, key: K, call: (old_value: D[K], new_value: D[K])=>void, update: boolean = true){
        let handle: Ab_PxiHandle_bA<D>;
        if(this.Ab_id_map_bA.has(data)) handle = this.Ab_record_bA.get(this.Ab_id_map_bA.get(data))[2];
        else abi.Ab_log_bA.Ab_tag_bA('无法对未代理的实例进行监听: orange', data);

        let path = handle.Ab_path_bA + '.' + key.toString();
		if(!this.Ab_call_pool_bA.has(path)) this.Ab_call_pool_bA.set(path, []);
		this.Ab_call_pool_bA.get(path).push(call);

        if(update){
			let [target, proxy] = this.Ab_record_bA.get(this.Ab_id_map_bA.get(data));
			call(target[key], proxy[key]);
		}

        return {path, call} as {path: string, call: Function};
    }

	/** 注销监听 */
	public static Ab_cancel_bA(info: ReturnType<typeof Ab_DataTransfer_bA.Ab_follow_bA>){
		if(this.Ab_call_pool_bA.has(info.path)){
            let list = this.Ab_call_pool_bA.get(info.path);
            if(list.length > 0) list.splice(list.indexOf(info.call), 1);
            else if(list.length <= 0) this.Ab_call_pool_bA.delete(info.path);
		}
	}

	/**
     * 取消指定的监听
     * @param data 要监听的数据
     * @param key 要监听的字段
     * @param call 更新时触发的回调函数
	 */
	public static Ab_out_bA<D extends Object, K extends abi.Ab_OmitKeys_bA<D, Function>>(data: D, key: K, call: (old_value: D[K], new_value: D[K])=>void){
        let handle: Ab_PxiHandle_bA<D> = this.Ab_record_bA.get(this.Ab_id_map_bA.get(data))[2];
		if(!handle) return void 0;

		let path = handle.Ab_path_bA + '.' + key.toString();
		this.Ab_cancel_bA({path, call});
	}

	/** 指定的路径是否被监听 */
	public static Ab_hasListen_bA<D extends Object, K extends abi.Ab_OmitKeys_bA<D, Function>>(data: D, key: K){
		let id = this.Ab_id_map_bA.get(data);
		if(id===undefined) return false;
		let handle = this.Ab_record_bA.get(id)[2];
		if(handle===undefined) return false;
		let path = handle.Ab_path_bA + '.' + key.toString();
		let list = this.Ab_call_pool_bA.get(path);
		return list===undefined ? false : list.length > 0;
	}


	/** 是否有任务正在执行中 */
	private static Ab_tasking_bA: boolean = false;
	/** 更新日志记录 */
	private static Ab_record_map_bA = new Map<string, [any, any]>();

	/** 动态延迟，为了解决子节点并发更新时，父节点更新的重复触发造成的性能浪费，逻辑上不能完全防止，目前没有发现异常，暂时如此 */
	private static Ab_delay_bA = (()=>{
		let c = new abi.Ab_CountAverage_bA();
		c.Ab_add_bA(30);
		return c;
	})();
	private static Ab_delay_stamp_bA = performance.now();
	private static Ab_updateDelay_bA(){
		let now = performance.now();
		let diff = now-Ab_DataTransfer_bA.Ab_delay_stamp_bA;
		Ab_DataTransfer_bA.Ab_delay_stamp_bA = now;
		if(diff<=30 && diff>0) Ab_DataTransfer_bA.Ab_delay_bA.Ab_add_bA(diff);
	}
	// ⬆⬆⬆ 该段代码的是为了防止，自节点的并发更新，导致父节点的更新事件重复触发的问题

	/** 打包生成任务 */
	private static Ab_packaging_bA(){
		if(this.Ab_record_map_bA.size===0) return void 0;

		let record = Array.from(Ab_DataTransfer_bA.Ab_record_map_bA);
		Ab_DataTransfer_bA.Ab_record_map_bA.clear();

		let list = record.filter(el=>this.Ab_call_pool_bA.has(el[0])).map(item=>{
			return {
				path: item[0],
				data: item[1]
			}
		});

		if(list.length>0) Ab_DataTransfer_bA.Ab_taskLoop_bA(list);
		else Ab_DataTransfer_bA.Ab_tasking_bA = false;
	}

	/** 循环执行任务列表中的任务 */
	private static async Ab_taskLoop_bA(list: {path: string, data: [any, any]}[]){
		while(list.length>0){
			let task = list.shift();
			//if(!task.path.includes('clock')) abi.Ab_log_bA.Ab_tag_bA('run task: green', task.path, ...task.data);
			await Promise.allSettled(Ab_DataTransfer_bA.Ab_call_pool_bA.get(task.path).map(f=>new Promise((s, j)=>{
				f(...task.data);
				s(void 0);
			})));
			Ab_DataTransfer_bA.Ab_distributeTask_bA(task);
		}

		if(Ab_DataTransfer_bA.Ab_record_map_bA.size > 0) Ab_DataTransfer_bA.Ab_packaging_bA();
		else Ab_DataTransfer_bA.Ab_tasking_bA = false;
	}

	/** 触发一个任务支线 */
	private static async Ab_distributeTask_bA(task: {path: string, data: [any, any]}){
		let path_list = task.path.split('.');
		// 触发被标记的代理监听
		if(Ab_DataTransfer_bA.Ab_monitor_call_bA.has(path_list[0])) Ab_DataTransfer_bA.Ab_monitor_call_bA.get(path_list[0]).forEach(f=>f(task.path, ...task.data));
	}

	/**
	 * 发布更新日志
	 * @param path 更新路径
	 * @param old 原始值
	 * @param value 更新值
	 */
	public static Ab_publish_bA(path: string, old: any, value: any){
		//abi.Ab_log_bA.Ab_tag_bA('publish-->:blue', Ab_DataTransfer_bA.Ab_tasking_bA, path, JSON.stringify([old, value]));

		Ab_DataTransfer_bA.Ab_record_map_bA.set(path, [old, value]);

		if(!Ab_DataTransfer_bA.Ab_tasking_bA){
			Ab_DataTransfer_bA.Ab_tasking_bA = true;
		// ⬇⬇⬇ 该段代码的是为了防止，字节的并发更新，导致父节点的更新事件重复触发的问题
			let id = setTimeout((dm: typeof Ab_DataTransfer_bA)=>{
				dm.Ab_packaging_bA();
				clearTimeout(id);
			}, Ab_DataTransfer_bA.Ab_delay_bA.Ab_average_bA, Ab_DataTransfer_bA);
		}else Ab_DataTransfer_bA.Ab_updateDelay_bA();
		// ⬆⬆⬆ 该段代码的是为了防止，字节的并发更新，导致父节点的更新事件重复触发的问题
	}
}
